#ifndef __BLOB_DEFINE__
#define __BLOB_DEFINE__


struct cblob_t
{
	const void *	Data;
	size_t			Length;

	cblob_t() : Data(0), Length(0){};

	cblob_t( CONST cblob_t& right ) : Data(right.Data), Length(right.Length)
	{
	};

	cblob_t& operator = ( CONST cblob_t& right )
	{
		Data = (right.Data), Length = (right.Length);
		return *this;
	}
	cblob_t( const void * b, size_t l ) : Data(b), Length(l)
	{
	};

	void dispose()
	{
		Data = 0;
		Length = 0;
	}

	~cblob_t() { ; }

	// safe, size check
	template < class T >
	bool get_t( T & t ) const
	{
		if( Length < sizeof(t) ) return false;
		t = *((T*)Data);
		return true;
	}

	// unsafe, no size check
	template < class T >
	T & ref_t()	const
	{
		return *((T*)Data);
	}

	// unsafe, no size check
	template < class T >
	T * asptr_t( size_t l = sizeof(T) )	const
	{
		if( l > Length ) return 0;
		return ((T*)Data);
	}

};

struct blob_t : cblob_t
{
	typedef void ( * free_t )( blob_t * );
	free_t			FreePtr;
	void			dispose() 
	{ 
		if( FreePtr ) FreePtr( this ); 
		Data = 0; Length = 0; FreePtr = 0; 
	};

	static void cpp_delete( blob_t * p )
	{
		if( !p ) return;
		if( p->Data ) { delete [] ((char*)(p->Data)); };
	}

	blob_t() : cblob_t(), FreePtr(0){};

	blob_t( cblob_t& right )
	{
		Data = (right.Data), Length = (right.Length);
		FreePtr = NULL;
	}

	blob_t( blob_t& right )
	{
		Data = (right.Data), Length = (right.Length), FreePtr = (right.FreePtr);
		right.FreePtr = 0;
	};

	template< class T >
	blob_t( T& r )
	{
		Data = &r;
		Length = sizeof(T);
		FreePtr = NULL;
	}

	blob_t&  operator = ( blob_t& right )
	{
		dispose();
		Data = (right.Data), Length = (right.Length), FreePtr = (right.FreePtr);
		right.FreePtr = 0;
		return *this;
	}
	blob_t&  operator = ( const cblob_t& right )
	{
		dispose();
		Data = (right.Data), Length = (right.Length);
		return *this;
	}

	blob_t( const void * b, size_t l ) : cblob_t(b,l), FreePtr(0)
	{}

	blob_t( const void * b, size_t l, free_t pfn )
		: cblob_t(b,l), FreePtr(pfn)
	{};

	~blob_t() { dispose(); }
};


#endif
